1
성능 격차의 이유 – 왜 NumPy를 확장해야 할까?
AI018Lesson 5
00:00

NumPy는 C 기반으로 만들어졌지만, 일부 계산 집약적인 알고리즘은 벡터화 장벽에 도달하게 되며, 이는 파이썬의 동적 특성으로 인한 본질적인 지연 시간이 고수준 추상화의 이점을 초과할 때 발생한다.

1. 인터프리터 세금 및 박싱

표준 파이썬 루프의 각 반복마다 동적 타입 검사와 참조 카운팅이 필요하다. 파이썬 스칼라를 사용하더라도, 원시적인 C 데이터를 파이썬 객체로 포장하는 '박싱' 과정은 $\text{logit}(p) = \log(p/(1-p))$ 같은 함수에서 막대한 성능 저하를 초래한다. C에서는 경계 조건을 처리하는 것이 훨씬 빠르다:

>>> logit(0) -> -inf
>>> logit(1) -> inf
>>> logit(2) -> nan
>>> logit(-2) -> nan

2. 중간 배열 부풀림

순수한 NumPy 표현식은 각 하위 연산마다 일시적인 메모리 버퍼를 생성한다. C-API를 통해 확장하면 커널 융합단일 패스로 로짓 변환을 계산할 수 있게 되어 보조 메모리 오버헤드 없이 수행된다.

3. 공간적 종속성

이웃 접근 패턴을 포함하는 연산, 예를 들어 2차원 스텐실:

$$B(I, J) = A(I, J) + (A(I-1, J) + A(I+1, J) + A(I, J-1) + A(I, J+1)) \cdot 0.5D0 + (A(I-1, J-1) + A(I-1, J+1) + A(I+1, J-1) + A(I+1, J+1)) \cdot 0.25D0$$

슬라이싱을 통해 효율적으로 표현하기 어렵고, 중복된 메모리 복사가 발생한다. C 확장 기능은 직접적인 캐시 정렬 포인터 연산을 가능하게 한다.

main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>